from PySide6.QtCore import QByteArray, Signal, QObject
from PySide6.QtNetwork import QUdpSocket, QHostAddress
from .AesCipher import AesCbc

class UdpClient(QObject):
    DateReceived = Signal(str, str, int)

    def __init__(self, encrypt):
        super().__init__()

        self.__encrypt = encrypt

        self.__peerIp = ""
        self.__peerPort = 0
        self.__QUdpSocket = QUdpSocket()

        self.__QUdpSocket.readyRead.connect(self.on_readPendingDatagrams)
        self.__QUdpSocket.bind(QHostAddress.Any)

    def __del__(self):
        if (self.__QUdpSocket is not None):
            self.__QUdpSocket.disconnectFromHost()
            self.__QUdpSocket.close()
            del self.__QUdpSocket
            self.__QUdpSocket = None

    def GetIP(self):
        return self.__peerIp

    def GetPort(self):
        return self.__peerPort

    def GetSocketPort(self):
        return self.__QUdpSocket.localPort()

    def Connect(self, ip, port):
        self.__peerIp = ip
        self.__peerPort = port
        self.SendData("{}");

    def SendData(self, jsonStr):
        sendData = QByteArray(AesCbc().encrypt(jsonStr)) if self.__encrypt else QByteArray(jsonStr)
        return (self.__QUdpSocket.writeDatagram(sendData, QHostAddress(self.__peerIp), self.__peerPort) > 0)
        
    def on_readPendingDatagrams(self):
        while (self.__QUdpSocket.hasPendingDatagrams()):
            buff, addr, port = self.__QUdpSocket.readDatagram(10240)
            if len(buff) > 0:
                try:
                    data = AesCbc().decrypt(str(buff, encoding='utf-8')) if self.__encrypt else str(buff, encoding='utf-8')
                except:
                    return
                
                if (len(data) > 0):
	            	#print(buff)

                    self.DateReceived.emit(data, QHostAddress(addr.toIPv4Address()).toString(), port)